Problem 1 |
Create a dialog application called Oscilloscope using Wintempla to display audio signals in the screen. Once the application has been created, edit the stdafx.h file removing the comments from #define WIN_DAC_ADC_SUPPORT. Cree una aplicación de diálogo llamada Oscilloscope usando Wintempla que mostrar señales de audio en la pantalla. Una vez creada la aplicación, edite el archivo stdafx.h removiendo el comentario de #define WIN_DAC_ADC_SUPPORT. |
Step A |
Open Wintempla, from the toolbar press the "Show All Controls in Toolbox" and insert an "Analog Digital Converter" as shown below. In the Events tab, be sure all events are unselected. Abra Wintempla, y desde la barra de herramientas presione "Show All Controls in Toolbox" e inserte un "Analog Digital Converter" como se muestra debajo. En la pestaña de eventos, asegúrese que todos los eventos están deseleccionados |
Step B |
Complete the GUI as shown below. Insert three sliders to control the Amplitude and Time scale (resolution) of each channel. Note that the two sliders for the amplitude must be vertical as shown below. Then, add the Hscroll event to the horizontal slider and the Vscroll event to the vertical sliders. Add a drop down list to select the input device. Complete the GUI como se muestra debajo. Inserte tres controles slider para la escala (resolución) en amplitud y en frecuencia de cada canal. Note que los dos sliders para la amplitud deben ser verticales como se muestra debajo. Entonces, agregue el evento Hscroll al slider horizontal y el evento Vscroll a los slider verticales. Agregue una drop down list para seleccionar el dispositivo de entrada. |
Step C |
Edit the Oscilloscope.h file and the Oscilloscope.cpp file to implement the three functions of the Mm::IAudioIn interface (observe that the Oscilloscopeclass is derived from Mm::IAudioIn). Remember that an interface is used to pass a set of functions to another function or another object. Edite los archivos Oscilloscope.h y Oscilloscope.cpp para implementar las tres funciones de la interface Mm::IAudioIn (observa que la clase Oscilloscopese deriva de Mm::IAudioIn). Recuerde que una interface es usada para pasar un conjunto de funciones a otra función u objeto. |
Oscilloscope.h |
#pragma once //______________________________________ Oscilloscope.h #include "resource.h" #define OSCILLOSCOPE_POINTS 1024 #define SAMPLING_FREQUENCY 44100 #define MILLISECONDS_PERIOD (1000.0/SAMPLING_FREQUENCY) class Oscilloscope : public Win::Dialog, public Mm::IAudioIn { public: Oscilloscope() { scaleTime = 50; scaleAmplitude1 = 50; scaleAmplitude2 = 50; } ~Oscilloscope() { } int scaleTime; int scaleAmplitude1; int scaleAmplitude2; //______________________________________________________________ Mm::IAudioIn void AudioInStarted(unsigned int samplesPerSec, unsigned int numbChannels, unsigned int bitsResolution); void AudioInData(unsigned int samplesPerSec, unsigned int numbChannels, unsigned int bitsResolution, WAVEHDR* waveHdr); void AudioInStopped(); protected: ... }; |
Oscilloscope.cpp |
... void Oscilloscope::Window_Open(Win::Event& e) { //________________________________________________________ ddDevice const int count = ::waveInGetNumDevs(); WAVEINCAPS wic; const int wsize= sizeof(WAVEINCAPS); for (int i = 0; i < count; i++) { if (::waveInGetDevCaps(i, &wic, wsize) == MMSYSERR_NOERROR) { ddDevice.Items.Add(wic.szPname, i); } } ddDevice.SelectedIndex = 0; //________________________________________________________ xyDisplay xyDisplay.CaptionX = L"Time (milliseconds)"; xyDisplay.CaptionY = L"Amplitude"; xyDisplay.MinX = 0.0; xyDisplay.MaxX = OSCILLOSCOPE_POINTS*MILLISECONDS_PERIOD; xyDisplay.MinY = -160000; xyDisplay.MaxY = 160000; xyDisplay.Graphs.Add(OSCILLOSCOPE_POINTS); // CH1 xyDisplay.Graphs.Add(OSCILLOSCOPE_POINTS); // CH2 for (int i = 0; i<OSCILLOSCOPE_POINTS; i++) { //____________________________________________ CH 1 xyDisplay.Graphs[0][i].x = i*MILLISECONDS_PERIOD; xyDisplay.Graphs[0][i].y = 0.0; //____________________________________________ CH 2 xyDisplay.Graphs[1][i].x = i*MILLISECONDS_PERIOD; xyDisplay.Graphs[1][i].y = 0.0; } xyDisplay.Graphs[0].Color = RGB(0, 0, 255); xyDisplay.Graphs[1].Color = RGB(255, 0, 0); // xyDisplay.RefreshAll(); //________________________________________________________ sldTime sldTime.SetRange(0, 100); sldTime.Position = 50; //________________________________________________________ sldCh1 sldCh1.SetRange(0, 100); sldCh1.Position = 50; //________________________________________________________ sldCh2 sldCh2.SetRange(0, 100); sldCh2.Position = 50; this->btOn.Enabled = true; this->btOff.Enabled = false; } void Oscilloscope::sldTime_Hscroll(Win::Event& e) { const int position = sldTime.Position; if (position != -1) { xyDisplay.MaxX = MILLISECONDS_PERIOD*102.4*position / 10.0; xyDisplay.RefreshAll(); } } void Oscilloscope::sldCh1_Vscroll(Win::Event& e) { const int position = sldCh1.Position; if (position != -1) scaleAmplitude1 = position; } void Oscilloscope::sldCh2_Vscroll(Win::Event& e) { const int position = sldCh2.Position; if (position != -1) scaleAmplitude2 = position; } void Oscilloscope::btOn_Click(Win::Event& e) { LPARAM deviceID = WAVE_MAPPER; ddDevice.GetSelectedData(deviceID); const wchar_t* error = adcInput.Start((unsigned int)deviceID, SAMPLING_FREQUENCY, 2, 16, 8*8192, this); if (error != NULL) { this->MessageBox(error, L"Oscilloscope", MB_OK | MB_ICONERROR); } } void Oscilloscope::btOff_Click(Win::Event& e) { adcInput.Stop(); } void Oscilloscope::AudioInStarted(unsigned int samplesPerSec, unsigned int numbChannels, unsigned int bitsResolution) { this->EnableCloseButton(false); this->btOn.Enabled = false; this->btOff.Enabled = true; this->ddDevice.Enabled = false; } void Oscilloscope::AudioInStopped() { this->EnableCloseButton(true); this->btOn.Enabled = true; this->btOff.Enabled = false; this->ddDevice.Enabled = true; //________________________________ Clean the graph for (int i = 0; i<OSCILLOSCOPE_POINTS; i++) { xyDisplay.Graphs[0][i].y = 0.0; xyDisplay.Graphs[1][i].y = 0.0; } xyDisplay.RefreshAll(); } void Oscilloscope::AudioInData(unsigned int samplesPerSec, unsigned int numbChannels, unsigned int bitsResolution, WAVEHDR* waveHdr) { const DWORD bytesRecorded = waveHdr->dwBytesRecorded; Sys::Sample16* data = (Sys::Sample16*)(waveHdr->lpData); if (bytesRecorded>0) { for (int i = 0; i<OSCILLOSCOPE_POINTS; i++) { xyDisplay.Graphs[0][i].y = (scaleAmplitude1 / 10.0)*(int)data[i].channel_1; xyDisplay.Graphs[1][i].y = (scaleAmplitude2 / 10.0)*(int)data[i].channel_2; } xyDisplay.RefreshGraphArea(); } } |